import _ from 'lodash';
import * as connectionManager from '../connectionManager';

import logger from '../../../common/logger';

import { AgentStatus } from '../../model/agent/type';
import { agentService } from '../../model/agent/service';
import { AgentSelectionStrategy, AgentSelectionStrategyFactory } from '../scheduler/agentSelectionStrategy';
import { BaseResponse, ModelParseParamRequest, ModelTreesRequest } from './simModelRequest';
class ParameterService {

  parseModelParam(modelParseParamReq: ModelParseParamRequest): Promise<BaseResponse> {
    return new Promise(async (resolve, reject) => {

      let agents = await agentService.findByProductAndStatus(modelParseParamReq.product, AgentStatus.ONLINE);

      if (modelParseParamReq.serverIdentity?.length) {
        agents = agents.filter(function (value, index, arr) {
          return modelParseParamReq.serverIdentity.includes(value.identity);
        });
      }

      if (_.isEmpty(agents)) {
        reject({
          success: false,
          message: `All agents with product = ${modelParseParamReq.product} are offline.`
        });
      }

      const strategy: AgentSelectionStrategy = AgentSelectionStrategyFactory.newSelectionStrategy(modelParseParamReq.product);
      const agent = await strategy.select(agents);
      if (agent) {
        modelParseParamReq.serverIdentity = agent.identity;
      }

      const connection = connectionManager.getConnection(modelParseParamReq.serverIdentity);
      if (connection) {
        connection.emit('model:parseParam', modelParseParamReq, result => {
          logger.info(`The model analysis result received from the agent is: ${JSON.stringify(result, null, 2)}`);
          resolve(result);
        });
      } else {
        reject({
          success: false,
          message: `can not get connection from ${modelParseParamReq.serverIdentity}`
        });
      }
    });
  }

  getModelTrees(modelTreesRequest: ModelTreesRequest): Promise<BaseResponse> {
    return new Promise(async (resolve, reject) => {
      const connection = connectionManager.getConnection(modelTreesRequest.serverIdentity);
      if (connection) {
        logger.info('emit model:fileTrees');
        connection.emit('model:fileTrees', modelTreesRequest.modelPath, (result) => {
          resolve(result);
        });
      } else {
        reject({
          success: false,
          message: `can not get connection from ${modelTreesRequest.serverIdentity}`
        });
      }
    });
  }
}

export const parameterService = new ParameterService();